{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## PaddlePaddle：高层API助你快速上手深度七日打卡营\n",
    "\n",
    "## 首日课程：使用简单的飞桨高层API完成了对手写数字图像的分类\n",
    "\n",
    "课程地址：https://aistudio.baidu.com/aistudio/course/introduce/6771\n",
    "\n",
    "## 1.一些基本概念的回顾\n",
    "\n",
    "神经网络的基本概念\n",
    "\n",
    "<img src='图片/神经网络.png'>\n",
    "\n",
    "开发深度学习应用的一般步骤\n",
    "\n",
    "<img src=\"图片/万能公式.png\" >\n",
    "\n",
    "\n",
    "\n",
    "## 2.程序实现中的关键\n",
    "\n",
    "### 2.1加载数据\n",
    "\n",
    "直接使用paddle.dataset中的API来加载数据而不用提前下载好数据集\n",
    "```\n",
    "paddle.vision.datasets.MNIST\n",
    "```\n",
    "飞桨的dateset可以使用`paddle.vision.datasets`或者`paddle.text.datasets`来加载，具体如下\n",
    "\n",
    "https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/02_paddle2.0_develop/02_data_load_cn.html#id2\n",
    "\n",
    "```\n",
    "视觉相关数据集： ['DatasetFolder', 'ImageFolder', 'MNIST', 'FashionMNIST', 'Flowers', 'Cifar10', 'Cifar100', 'VOC2012']\n",
    "自然语言相关数据集： ['Conll05st', 'Imdb', 'Imikolov', 'Movielens', 'UCIHousing', 'WMT14', 'WMT16']\n",
    "```\n",
    "\n",
    "### 2.2网络结构\n",
    "\n",
    "具体结构：\n",
    "\n",
    "<img src='图片/模型.png'>\n",
    "\n",
    "其中激活函数使用了Relu，在paddle官网上还有别的激活函数：\n",
    "\n",
    "`ELU、GELU、Hardshrink、Hardtanh、HSigmoid、LeakyReLU、LogSigmoid、 LogSoftmax、PReLU、ReLU、ReLU6、SELU、Sigmoid、Softmax、Softplus、 Softshrink、Softsign、Tanh、Tanhshrink`\n",
    "\n",
    "具体可以参考：https://www.paddlepaddle.org.cn/searchdoc?q=Activation&language=zh&version=2.0\n",
    "\n",
    "### 2.3优化器\n",
    "\n",
    "优化器选用了Adam\n",
    "\n",
    "`class paddle.optimizer.Adam(learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-08, parameters=None, weight_decay=None, grad_clip=None, name=None, lazy_mode=False)`\n",
    "\n",
    "具体的实现\n",
    "\n",
    "$\\begin{split}\\\\t = t + 1\\end{split}$\n",
    "\n",
    "$moment\\_1\\_out=\\beta_1∗moment\\_1+(1−\\beta_1)∗grad$\n",
    "\n",
    "$moment\\_2\\_out=\\beta_2∗moment\\_2+(1−\\beta_2)∗grad*grad$\n",
    "\n",
    "$learning\\_rate=learning\\_rate*\\frac{\\sqrt{1-\\beta_2^t}}{1-\\beta_1^t}$\n",
    "\n",
    "$\\begin{split}param\\_out=param-learning\\_rate*\\frac{moment\\_1}{\\sqrt{moment\\_2}+\\epsilon}\\\\\\end{split}$\n",
    "\n",
    "在李宏毅老师的课上说了Adam优化器的原理\n",
    "\n",
    "<img src='图片/Adam.png'>\n",
    "\n",
    "这个慢慢推公式就好，直接解释的话，就是用一阶矩和二阶矩来动态调整学习率\n",
    "\n",
    "其他各种优化器可以参考：\n",
    "\n",
    "https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/optimizer/Overview_cn.html#paddle-optimizer\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "#因为paddle版本的问题，有时候会出现不必要的警告，选择忽略它们\n",
    "import paddle\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练集样本量: 60000，验证集样本量: 10000\n"
     ]
    }
   ],
   "source": [
    "import paddle.vision.transforms as T\n",
    "\n",
    "# 数据的加载和预处理\n",
    "transform = T.Normalize(mean=[127.5], std=[127.5])\n",
    "\n",
    "# 训练数据集\n",
    "train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=transform)\n",
    "\n",
    "# 评估数据集\n",
    "eval_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform)\n",
    "\n",
    "print('训练集样本量: {}，验证集样本量: {}'.format(len(train_dataset), len(eval_dataset)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 模型网络结构搭建\n",
    "network = paddle.nn.Sequential(\n",
    "    paddle.nn.Flatten(),           # 拉平，将 (28, 28) => (784)\n",
    "    paddle.nn.Linear(784, 512),    # 隐层：线性变换层\n",
    "    paddle.nn.ReLU(),              # 激活函数\n",
    "    paddle.nn.Linear(512, 10)      # 输出层\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "---------------------------------------------------------------------------\n",
      " Layer (type)       Input Shape          Output Shape         Param #    \n",
      "===========================================================================\n",
      "   Flatten-1       [[1, 28, 28]]           [1, 784]              0       \n",
      "   Linear-1          [[1, 784]]            [1, 512]           401,920    \n",
      "    ReLU-1           [[1, 512]]            [1, 512]              0       \n",
      "   Linear-2          [[1, 512]]            [1, 10]             5,130     \n",
      "===========================================================================\n",
      "Total params: 407,050\n",
      "Trainable params: 407,050\n",
      "Non-trainable params: 0\n",
      "---------------------------------------------------------------------------\n",
      "Input size (MB): 0.00\n",
      "Forward/backward pass size (MB): 0.01\n",
      "Params size (MB): 1.55\n",
      "Estimated Total Size (MB): 1.57\n",
      "---------------------------------------------------------------------------\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'total_params': 407050, 'trainable_params': 407050}"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#类似与TF或者PT的对模型的直观显现的功能\n",
    "model = paddle.Model(network)\n",
    "model.summary((1, 28, 28))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The loss value printed in the log is the current step, and the metric is the average value of previous step.\n",
      "Epoch 1/5\n",
      "step 938/938 [==============================] - loss: 0.2044 - acc: 0.9130 - 21ms/step          \n",
      "Eval begin...\n",
      "The loss value printed in the log is the current batch, and the metric is the average value of previous step.\n",
      "step 157/157 [==============================] - loss: 0.0385 - acc: 0.9496 - 10ms/step          \n",
      "Eval samples: 10000\n",
      "Epoch 2/5\n",
      "step 938/938 [==============================] - loss: 0.0527 - acc: 0.9596 - 17ms/step          \n",
      "Eval begin...\n",
      "The loss value printed in the log is the current batch, and the metric is the average value of previous step.\n",
      "step 157/157 [==============================] - loss: 0.0107 - acc: 0.9628 - 10ms/step          \n",
      "Eval samples: 10000\n",
      "Epoch 3/5\n",
      "step 938/938 [==============================] - loss: 0.0082 - acc: 0.9692 - 20ms/step          \n",
      "Eval begin...\n",
      "The loss value printed in the log is the current batch, and the metric is the average value of previous step.\n",
      "step 157/157 [==============================] - loss: 0.0045 - acc: 0.9694 - 9ms/step          \n",
      "Eval samples: 10000\n",
      "Epoch 4/5\n",
      "step 938/938 [==============================] - loss: 0.0053 - acc: 0.9734 - 18ms/step          \n",
      "Eval begin...\n",
      "The loss value printed in the log is the current batch, and the metric is the average value of previous step.\n",
      "step 157/157 [==============================] - loss: 0.0040 - acc: 0.9659 - 10ms/step          \n",
      "Eval samples: 10000\n",
      "Epoch 5/5\n",
      "step 938/938 [==============================] - loss: 0.1356 - acc: 0.9761 - 22ms/step          \n",
      "Eval begin...\n",
      "The loss value printed in the log is the current batch, and the metric is the average value of previous step.\n",
      "step 157/157 [==============================] - loss: 8.2717e-04 - acc: 0.9737 - 10ms/step      \n",
      "Eval samples: 10000\n"
     ]
    }
   ],
   "source": [
    "# 配置优化器、损失函数、评估指标\n",
    "model.prepare(paddle.optimizer.Adam(learning_rate=0.001, parameters=network.parameters()),\n",
    "              paddle.nn.CrossEntropyLoss(),\n",
    "              paddle.metric.Accuracy())\n",
    "              \n",
    "# 启动模型全流程训练\n",
    "model.fit(train_dataset,  # 训练数据集\n",
    "          eval_dataset,   # 评估数据集\n",
    "          epochs=5,       # 训练的总轮次\n",
    "          batch_size=64,  # 训练使用的批大小\n",
    "          verbose=1)      # 日志展示形式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Eval begin...\n",
      "The loss value printed in the log is the current batch, and the metric is the average value of previous step.\n",
      "step 10000/10000 [==============================] - loss: 1.1921e-07 - acc: 0.9737 - 3ms/step          \n",
      "Eval samples: 10000\n",
      "{'loss': [1.192093e-07], 'acc': 0.9737}\n"
     ]
    }
   ],
   "source": [
    "# 模型评估，根据prepare接口配置的loss和metric进行返回\n",
    "result = model.evaluate(eval_dataset, verbose=1)\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Predict begin...\n",
      "step 10000/10000 [==============================] - 3ms/step          \n",
      "Predict samples: 10000\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 进行预测操作\n",
    "result = model.predict(eval_dataset)\n",
    "\n",
    "# 定义画图方法\n",
    "def show_img(img, predict):\n",
    "    plt.figure()\n",
    "    plt.title('predict: {}'.format(predict))\n",
    "    plt.imshow(img.reshape([28, 28]), cmap=plt.cm.binary)\n",
    "    plt.show()\n",
    "\n",
    "# 抽样展示\n",
    "indexs = [15,211]\n",
    "\n",
    "for idx in indexs:\n",
    "    show_img(eval_dataset[idx][0], np.argmax(result[0][idx]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 读取单张图片\n",
    "image = eval_dataset[501][0]\n",
    "\n",
    "# 单张图片预测\n",
    "result = model.predict_batch([image])\n",
    "\n",
    "# 可视化结果\n",
    "show_img(image, np.argmax(result))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The loss value printed in the log is the current step, and the metric is the average value of previous step.\n",
      "Epoch 1/2\n",
      "step 938/938 [==============================] - loss: 0.0605 - acc: 0.9785 - 14ms/step          \n",
      "Eval begin...\n",
      "The loss value printed in the log is the current batch, and the metric is the average value of previous step.\n",
      "step 157/157 [==============================] - loss: 0.0013 - acc: 0.9752 - 9ms/step           \n",
      "Eval samples: 10000\n",
      "Epoch 2/2\n",
      "step 938/938 [==============================] - loss: 0.0046 - acc: 0.9819 - 19ms/step          \n",
      "Eval begin...\n",
      "The loss value printed in the log is the current batch, and the metric is the average value of previous step.\n",
      "step 157/157 [==============================] - loss: 2.9152e-04 - acc: 0.9760 - 10ms/step      \n",
      "Eval samples: 10000\n"
     ]
    }
   ],
   "source": [
    "# 保存用于后续继续调优训练的模型\n",
    "model.save('finetuning/mnist')\n",
    "\n",
    "from paddle.static import InputSpec\n",
    "\n",
    "\n",
    "# 模型封装，为了后面保存预测模型，这里传入了inputs参数\n",
    "model_2 = paddle.Model(network, inputs=[InputSpec(shape=[-1, 28, 28], dtype='float32', name='image')])\n",
    "\n",
    "# 加载之前保存的阶段训练模型\n",
    "model_2.load('finetuning/mnist')\n",
    "\n",
    "# 模型配置\n",
    "model_2.prepare(paddle.optimizer.Adam(learning_rate=0.001, parameters=network.parameters()),\n",
    "                paddle.nn.CrossEntropyLoss(),\n",
    "                paddle.metric.Accuracy())\n",
    "\n",
    "# 模型全流程训练\n",
    "model_2.fit(train_dataset, \n",
    "            eval_dataset,\n",
    "            epochs=2,\n",
    "            batch_size=64,\n",
    "            verbose=1)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:paddlepaddle]",
   "language": "python",
   "name": "conda-env-paddlepaddle-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
